package com.ruoyi.dm.component.den;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RuntimeUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.CollectFileTypeConstants;
import com.ruoyi.common.utils.biz.BizModule;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.dm.component.DataStrategy;
import com.ruoyi.dm.component.manager.DensityDataManager;
import com.ruoyi.dm.domain.BO.ResReturnBO;
import com.ruoyi.dm.domain.po.AirCollectRecordPO;
import com.ruoyi.utils.GpsTimeUtll;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.input.ReversedLinesFileReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * 空间 密度数据策略
 */
@Component
@Slf4j
public class NewDenstiyDataStrategy implements DataStrategy<AirCollectRecordPO> {

    @Autowired
    private DensityDataManager densityDataManager;

    @Override
    public AirCollectRecordPO makeupPo(AirCollectRecordPO po) {

        String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT)+po.getFilePath();
        File path = new File(fullPath, po.getFileName());
        ReversedLinesFileReader reader = null;
        try {
            reader = ReversedLinesFileReader.builder().setFile(path).get();
            String line = "";
            while (null != (line=reader.readLine())) {
                // 截取最新数据时间
                // 1964-04-09 00:00:00
                if (StringUtils.hasLength(line)) {
                    String str =  line.substring(0,10);
                    TemporalAccessor parse = DateTimeFormatter.ofPattern("yyyy-MM-dd").parse(str);
                    po.setFileDate(LocalDate.from(parse));
                    break;
                }
            }
        } catch (Exception e) {
            log.error("解析时间异常",e);
        }finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    //ignore
                }
            }
        }
        return po;
    }


    @Override
    public String pythonCmd(String satellite, String dataType, String filePath, String method, Integer year) {

        return null;
    }

    //将数据 转换为 岳博接受的格式
    @Override
    public ResReturnBO analysis(String file) throws Exception {
        //1 将文件转为岳博的格式
        //首行是表头
        //Time(UTC),  Altitude(m),  Geodetic LON(degree),     Geodetic LAT(degree),  Density(kg/m3)
        //2021-09-06 12:15:19     392896.0     -96.188    -40.421    9.34e-13
        List<String> lines = FileUtil.readLines(file, "utf-8");
        //先判断是否为UTC 时间数据
        int gpsSec = 0;
        boolean isUtc = false;

        for (String line : lines) {
            if (line.startsWith("#")) {
                // #为注释
                continue;
            }
            String[] split = line.split("\\s+");
            if ("UTC".equals(split[2])) {
                isUtc = true;
            }else {
                //判断闰秒
                LocalDate parse = LocalDate.parse(split[0], DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                gpsSec = GpsTimeUtll.secBetweenGpsAndUtc(parse);
            }
            break;
        }

        List<InnerBo> boList = new ArrayList<>();
        for (String line : lines) {
            if (line.startsWith("#")) {
                // #为注释
                continue;
            }
            String[] split = line.split("\\s+");
            InnerBo map = new InnerBo();
            map.setAlt(Double.valueOf(split[3]));
            map.setLon(Double.valueOf(split[4]));
            map.setLAT(Double.valueOf(split[5]));
            try {
                map.setDensity(new BigDecimal(split[8]));
            }catch (Exception e) {
                log.error("{} 异常",file,e);
            }
            LocalDateTime parse = LocalDateTime.parse(split[0]+split[1], DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss.SSS"));
            if (isUtc) {
                //utc 无需改变
                map.setTime(parse);
            }else {
                //gps 需 考虑闰秒
                LocalDateTime localDateTime = parse.plusSeconds(-gpsSec);
                map.setTime(localDateTime);
            }
            boList.add(map);
        }
        //将文件 修改格式
        File tmpFile = new File(PathUtil.tmpModuleDir(BizModule.COLLECT) +"/tmpfile/"+new File(file).getName());
        FileUtil.writeLines(ListUtil.of("Time(UTC),  Altitude(m),  Geodetic LON(degree), Geodetic LAT(degree),  Density(kg/m3)"),tmpFile,"utf-8");
        FileUtil.writeLines(boList,tmpFile,"utf-8",true);
        log.info("{} 转储 {}",file,tmpFile);

        String fileType = CollectFileTypeConstants.TYPE_DEN;
        String outPath = PathUtil.outputModuleDir(BizModule.COLLECT) + PathUtil.moduleDirs().getCollect().get("result") + "/" + fileType;
        FileUtil.mkdir(outPath);
        String logPath = PathUtil.tmpModuleDir(BizModule.COLLECT) + PathUtil.moduleDirs().getCollect().get("result") + "/" + fileType;
        FileUtil.mkdir(logPath);
        String script = PathUtil.codeModuleDir(BizModule.COLLECT) + PathUtil.moduleDirs().getCollect().get("densityScript");
        String tmpPath = PathUtil.tmpModuleDir(BizModule.COLLECT) + PathUtil.moduleDirs().getCollect().get("result");
        File inputFile = new File(tmpPath, tmpFile.getName() + ".json");
        //将参数写入文件
        LinkedHashMap<String, Object> object = new LinkedHashMap<>();
        //必需按这个顺序
        object.put("FILE_PATH", tmpFile.getAbsolutePath());
        object.put("RESULT_PATH", outPath);
        //这些参数是固定的
        object.put("threshold_density", 2.3);
        object.put("threshold_altitude", 1.2);
        String param = JSON.toJSONString(object);
        FileUtil.writeString(param, inputFile, StandardCharsets.UTF_8);
        String[] cmdLines = new String[3];
        cmdLines[0] = "python";
        cmdLines[1] = script;
        cmdLines[2] = inputFile.getAbsolutePath();
        String commond = ArrayUtil.join(cmdLines, " ");
        log.info("拼接脚本:{},{}", commond, param);
        String res = "";
        synchronized ("analysisAir") {
            res = RuntimeUtil.execForStr(commond);
        }
        log.info("解析结果:{}", res);
        tmpFile.delete();
        ResReturnBO resObj = JSON.parseObject(res, ResReturnBO.class);


        return resObj;
    }

    @Override
    public void save(String satellite, String outFile) throws Exception {
        densityDataManager.saveDensityData(satellite,outFile);
    }

    public static void main(String[] args) throws Exception {
        NewDenstiyDataStrategy newDenstiyDataStrategy = new NewDenstiyDataStrategy();
        newDenstiyDataStrategy.analysis("D:\\Program Files\\WXwork\\WXWork\\1688853796436234\\Cache\\File\\2024-11\\GA_DNS_ACC_2004_01_v01.txt");
    }
}

